package com.squirrel.serialportcore.machine.init.after;

import com.squirrel.serialportcore.common.CommonBase;
import com.squirrel.serialportcore.common.ContentBase;
import com.squirrel.serialportcore.common.SerialPortProperties;
import com.squirrel.serialportcore.exception.CoreException;
import com.squirrel.serialportcore.machine.consumer.SerialPortListener;
import com.squirrel.serialportcore.machine.operator.BasicsOperator;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import java.util.TooManyListenersException;


/**
 * 串口初始化 嵌入Spring启动流程之中
 *
 * @author Squbi
 * @date 2021/2/25 9:50
 */
@Component
public class SerialPortInitializer {
    private static Logger logger = LoggerFactory.getLogger(SerialPortInitializer.class);

    private BasicsOperator operator;

    private RabbitTemplate rabbitTemplate;

    SerialPortInitializer(BasicsOperator operator, RabbitTemplate rabbitTemplate) {
        this.operator = operator;
        this.rabbitTemplate = rabbitTemplate;
    }

    public void initSinglePort(String portName) {
        //获取配置初始化 如果不存在 则初始默认配置
        SerialPortProperties portProperties = CommonBase.getJsonProperty().getPortProperty().get(portName);
        logger.debug(" -debug- 初始化串口 {} 配置 {}", portName, portProperties);
        if (portProperties == null) {
            portProperties = new SerialPortProperties();
        }
        //储存配置
        ContentBase.getSerialPortProperties().put(portName, portProperties);
        //打开串口
        SerialPort serialPort = operator.openSerialPort(portName);
        logger.debug(" -debug- 已打开串口 {} 正在设置参数并配置监听", portName);
        //设置参数
        try {
            serialPort.setSerialPortParams(portProperties.getBitRate(),
                    portProperties.getDataBits(), portProperties.getStopBits(),
                    portProperties.getCheckParity());
        } catch (UnsupportedCommOperationException e) {
            throw new CoreException(logger, e, " 设置串口 {} 参数 {} 时出错 {} ",
                    portName, portProperties, e.getMessage());
        }
        //配置监听
        serialPort.notifyOnDataAvailable(true);
        SerialPortListener listener = new SerialPortListener(portName, rabbitTemplate);
        try {
            serialPort.addEventListener(listener);
        } catch (TooManyListenersException e) {
            throw new CoreException(logger, e, " 配置串口 {} 监听 {} 时出错 {} ",
                    portName, listener, e.getMessage());
        }
        //存储串口以备用
        ContentBase.getSerialPortMap().put(portName, serialPort);
        logger.debug(" -debug- 串口 {} 参数与监听已配置", portName);
    }
}

